package  drongo.desktop.undo.shortKey
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.utils.Dictionary;

	/**
	 * 快捷键系统 
	 * @author 蝈蝈
	 */	
	public class ShortKeySystem
	{
		/**
		 * 用于指定内部在keyboard事件发生时什么情况下应该忽略对该事件的响应 function(e:KeyboardEvent):Boolean
		 */		
		public var passFunction:Function;
		private var callBack:Function;
		public var keysMap:Dictionary;
		public function ShortKeySystem(stage:Stage,p_callBack:Function)
		{
			this.keysMap		= new Dictionary();
			this.callBack	= p_callBack;
			this._stage=stage;
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,keyBoardEventHandler,2000);
			this.stage.addEventListener(KeyboardEvent.KEY_UP,keyBoardEventHandler,2000);
			this.stage.addEventListener(Event.DEACTIVATE,onDeactivate);
			this.stage.addEventListener(Event.ACTIVATE,onActivate);
		}
		private function onActivate(e:Event):void{
			stage.addEventListener(KeyboardEvent.KEY_DOWN,keyBoardEventHandler,2000);
			stage.addEventListener(KeyboardEvent.KEY_UP,keyBoardEventHandler,2000);
		}
		private function onDeactivate(e:Event):void{
			keysMap=new Dictionary();
			this.stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyBoardEventHandler);
			this.stage.removeEventListener(KeyboardEvent.KEY_UP,keyBoardEventHandler);
		}
		private  var _stage:Stage;
		private  function get stage():Stage{
			return _stage;
		}
		public var isCtrl:Boolean;
		public var isShift:Boolean;
		private function keyBoardEventHandler(e:KeyboardEvent):void{
			if(passFunction!=null&&passFunction(e)){
				return;
			}
			//这是中文输入法引起的问题
			if(e.keyCode==229){
				return;
			}
			isCtrl=e.ctrlKey;
			isShift=e.shiftKey;
			switch(e.type)
			{
				case KeyboardEvent.KEY_DOWN:
					//trace("down",e.keyCode);
					keysMap[e.keyCode]=true;
					checkShortKey();
					break;
				case KeyboardEvent.KEY_UP:
					//trace("up",e.keyCode);
					delete keysMap[e.keyCode];
					break;
			}
		}
		private var helpArray:Array=[];
		private function checkShortKey():void{
			helpArray.length=0;
			var code:uint;
			for(var key:* in keysMap) 
			{
				code=uint(key);
				helpArray.push(code);
			}
			if(helpArray.length==0){
				return;
			}
			var keyCode:String=ShortKeyData.getKey(helpArray);
			for each (var data:ShortKeyData in shortKeyDataList) 
			{
				if(data.keyCode==keyCode&&data.focusTarget==focusTarget){
					if(callBack!=null){
						callBack(data.operate);
					}
					return;
				}
			}
		}
		private var shortKeyDataList:Vector.<ShortKeyData>=new Vector.<ShortKeyData>();
		private var registerSheet:Dictionary=new Dictionary();
		//=================================================================焦点对象管理==============================================================//
		/**
		 * 注册一个快捷键 
		 * @param operateKey									操作码
		 * @param keyCodes										按键列表
		 * @param focusTarget									焦点对象
		 * @param info													描述
		 */
		public function register(operateKey:String,keyCodes:Array,focusTarget:String=null,info:String=null):void{
			var key:String=ShortKeyData.getOperateKey(operateKey,keyCodes,focusTarget);
			if(registerSheet[key]){
				throw new Error("重复注册！");
			}
			var index:uint=shortKeyDataList.push(new ShortKeyData(operateKey,keyCodes,focusTarget,info));
			registerSheet[key]=index;
		}
		/**
		 * 取消快捷键 
		 * @param operateKey									操作码
		 * @param keyCodes										按键列表
		 * @param focusTarget									焦点对象
		 */		
		public function unregister(operate:String,keyCodes:Array,focusTarget:String=null):void{
			var key:String=ShortKeyData.getOperateKey(operate,keyCodes,focusTarget);
			var index:int=registerSheet[key];
			if(index>=0){
				shortKeyDataList.splice(index,1);
			}
		}
		//==================================焦点对象管理===============================//
		public function get focusTarget():String { 
			return _focusTarget; 
		}
		private var _focusTarget:String;
		public function set focusTarget(value:String):void
		{
			if (_focusTarget == value)
				return;
			_focusTarget = value;
		}
		/**
		 * 获取操作快捷键文字描述 
		 * @param focusTarget
		 * @param operater
		 * @return
		 */
		public function getOperaterShortcurtToString(operater:String,focusTarget:String=null):String{
			for each (var i:ShortKeyData in shortKeyDataList) 
			{
				if(i.operate==operater&&(i.focusTarget==focusTarget||focusTarget=="")){
					return i.keyCodeString;
				}
			}
			return "";
		}
		public function decode():XML{
			var xml:XML=<root></root>;
			for each (var data:ShortKeyData in shortKeyDataList) 
			{
				xml.appendChild(ShortKeyData.Decode(data));
			}
			return xml;
		}
	}
}